/**
 * 模板处理器类，用于将静态HTML转换为动态模板
 */
class TemplateProcessor {
    constructor() {
        this.templates = new Map(); // 存储所有注册的模板类型配置
    }

    /**
     * 注册模板类型
     * @param {string} type - 模板类型标识
     * @param {Object} config - 模板配置对象
     */
    register(type, config) {
        this.templates.set(type, config);
    }

    /**
     * 处理单个元素，根据类型配置设置属性或内容
     * @param {HTMLElement} element - 要处理的DOM元素
     * @param {Object} typeConfig - 模板类型配置
     */
    processElement(element, typeConfig) {
        const { fields } = typeConfig;
        // 遍历所有字段配置
        Object.entries(fields).forEach(([attr, template]) => {
            if (!element.hasAttribute(attr)) return;
            
            // 保持模板语法不变
            const value = template.replace(/\{@:(.*?):@\}/g, (match, field) => {
                return `{@:${field}:@}`;
            });

            // 根据元素类型设置不同属性
            switch(element.tagName) {
                case 'A': element.setAttribute('href', value); break; // 链接设置href
                case 'IMG': element.setAttribute('src', value); break; // 图片设置src
                default: element.innerHTML = value; // 其他元素设置内容
            }
        });
    }

    /**
     * 处理整个组件
     * @param {HTMLElement} component - 要处理的DOM组件
     */
    processComponent(component) {
        const type = component.getAttribute('data-czkj'); // 获取组件类型
        if (!type || !this.templates.has(type)) return;

        const typeConfig = this.templates.get(type);
        const listElements = this.getTopLevelElements(component, typeConfig);
        
        // 获取新闻模块的特殊属性
        const limit = component.getAttribute('data-limit') || '0,3'; // 显示条数限制
        const topid = component.getAttribute('data-topid') || '4241'; // 栏目ID

        // 处理每个列表元素
        listElements.forEach(listElement => {
            if (type === 'news') {
                // 新闻模块需要额外参数
                this.processListElement(listElement, typeConfig, type, { limit, topid });
            } else {
                this.processListElement(listElement, typeConfig, type);
            }
        });
    }

    /**
     * 获取顶级列表元素
     * @param {HTMLElement} component - 父组件
     * @param {Object} typeConfig - 模板类型配置
     * @returns {Array} 顶级元素数组
     */
    getTopLevelElements(component, typeConfig) {
        const listElements = [];
        // 查找所有符合列表属性的元素
        const allElements = component.querySelectorAll(`[${typeConfig.listAttr}]`);
        
        // 过滤出顶级元素（不被其他列表元素包含的元素）
        allElements.forEach(el => {
            if (!el.closest(`[${typeConfig.listAttr}]`)) {
                listElements.push(el);
            }
        });
        
        return listElements.length ? listElements : [component]; // 默认返回组件本身
    }

    /**
     * 处理列表元素
     * @param {HTMLElement} listElement - 列表元素
     * @param {Object} typeConfig - 模板类型配置
     * @param {string} type - 模板类型
     * @param {Object} [options] - 可选参数
     * @param {string} [options.limit] - 显示条数限制（新闻模块用）
     * @param {string} [options.topid] - 栏目ID（新闻模块用）
     */
    processListElement(listElement, typeConfig, type, { limit, topid } = {}) {
        const items = Array.from(listElement.children);
        if (!items.length) return;

        // 查找所有data-czkj-*="list"的模块
        const moduleLists = this.findModuleLists(listElement);
        // 准备模块模板（保留第一个子项）
        const firstModuleItems = this.prepareModuleTemplates(moduleLists, typeConfig);

        // 处理每个模块内容
        moduleLists.forEach(moduleList => {
            moduleList.innerHTML = ''; // 清空模块内容
            
            if (firstModuleItems.has(moduleList)) {
               const firstChild = firstModuleItems.get(moduleList);
               // 获取开始模板（支持函数和字符串两种形式）
               const startTemplate = typeof typeConfig.start === 'function'
                   ? type === 'news' 
                       ? typeConfig.start(moduleList, limit, topid) // 新闻模块传入参数
                       : typeConfig.start(moduleList)
                   : typeConfig.start;
               const endTemplate = typeConfig.end; // 结束模板
               
               // 插入模板标记和保留的第一个子项
               moduleList.insertAdjacentHTML('beforeend', startTemplate);
               moduleList.appendChild(firstChild);
               moduleList.insertAdjacentHTML('beforeend', endTemplate);
               
               // 处理字段替换
               Object.keys(typeConfig.fields).forEach(attr => {
                   Array.from(moduleList.querySelectorAll(`[${attr}]`)).forEach(el => {
                       this.processElement(el, typeConfig);
                   });
               });
            }
        });

        // 特殊处理导航菜单
        this.addListLevelTemplates(listElement, typeConfig, type, items);

        // 只保留第一个列表项（作为模板）
        if (items.length > 1) {
            for (let i = 1; i < items.length; i++) {
                items[i].remove();
            }
        }
    }

    /**
     * 查找所有带有data-czkj-*="list"属性的模块
     * @param {HTMLElement} listElement - 列表元素
     * @returns {Array} 匹配的模块元素数组
     */
    findModuleLists(listElement) {
        const allElements = listElement.getElementsByTagName('*');
        return Array.from(allElements).filter(el => {
            return Array.from(el.attributes).some(attr => 
                attr.name.startsWith('data-czkj-') && 
                attr.value.replace(/"/g, '').trim() === 'list'
            );
        });
    }

    /**
     * 准备模块模板（保留每个模块的第一个子项）
     * @param {Array} moduleLists - 模块列表
     * @param {Object} typeConfig - 模板类型配置
     * @returns {Map} 模块与其第一个子项的映射
     */
    prepareModuleTemplates(moduleLists, typeConfig) {
        const firstModuleItems = new Map();
        moduleLists.forEach(moduleList => {
            const children = Array.from(moduleList.children);
            if (children.length > 0) {
                const firstChild = children[0].cloneNode(true);
                firstModuleItems.set(moduleList, firstChild);
            }
        });
        return firstModuleItems;
    }

    /**
     * 添加列表级别模板（特殊处理导航菜单）
     * @param {HTMLElement} listElement - 列表元素
     * @param {Object} typeConfig - 模板类型配置
     * @param {string} type - 模板类型
     * @param {Array} items - 子项数组
     */
    addListLevelTemplates(listElement, typeConfig, type, items) {
        // 只处理导航菜单的特殊逻辑
        if (type === 'nav') {
            const firstItem = items[0];
            // 处理二级菜单
            const subMenu = firstItem.querySelector('[data-czkj-nav-child]');
            if (subMenu) {
                const firstChildItem = subMenu.firstElementChild;
                if (firstChildItem) {
                    firstChildItem.insertAdjacentText('beforebegin',
                        "{haedu:children eachparam[level='1'] /haedu}");
                    firstChildItem.insertAdjacentText('afterend', "{/endhaedu}");

                    // 删除多余的子菜单项
                    const childItems = Array.from(subMenu.children).filter(
                        child => child.tagName && child.tagName !== 'TEMPLATE'
                    );
                    if (childItems.length > 1) {
                        for (let i = 1; i < childItems.length; i++) {
                            childItems[i].remove();
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理字段替换
     * @param {HTMLElement} listElement - 列表元素
     * @param {Object} typeConfig - 模板类型配置
     */
    processFields(listElement, typeConfig) {
        Object.keys(typeConfig.fields).forEach(attr => {
            Array.from(listElement.querySelectorAll(`[${attr}]`)).forEach(el => {
                this.processElement(el, typeConfig);
            });
        });
    }

    /**
     * 只保留第一个列表项
     * @param {Array} items - 子项数组
     */
    keepFirstItemOnly(items) {
        if (items.length > 1) {
            for (let i = 1; i < items.length; i++) {
                items[i].remove();
            }
        }
    }

    /**
     * 处理模块内容
     * @param {Array} moduleLists - 模块列表
     * @param {Map} firstModuleItems - 模块与其第一个子项的映射
     * @param {Object} typeConfig - 模板类型配置
     */
    processModuleContents(moduleLists, firstModuleItems, typeConfig) {
        moduleLists.forEach(moduleList => {
            moduleList.innerHTML = '';
            
            if (firstModuleItems.has(moduleList)) {
                const firstChild = firstModuleItems.get(moduleList);
                const startTemplate = typeof typeConfig.start === 'function'
                    ? typeConfig.start(moduleList)
                    : typeConfig.start;
                const endTemplate = typeConfig.end;
                
                moduleList.insertAdjacentHTML('beforeend', startTemplate);
                moduleList.appendChild(firstChild);
                moduleList.insertAdjacentHTML('beforeend', endTemplate);
            }
        });
    }

    /**
     * 处理HTML字符串
     * @param {string} htmlString - 要处理的HTML字符串
     * @returns {string} 处理后的HTML字符串
     */
    processHtml(htmlString) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(htmlString, "text/html");

        this.templates.forEach((config, type) => {
            doc.querySelectorAll(config.selector).forEach(component => {
                this.processComponent(component);
            });
        });

        return doc.body.innerHTML;
    }
}

// 创建实例并注册模板类型
const templateProcessor = new TemplateProcessor();

// 注册导航模板
templateProcessor.register('nav', {
    selector: '[data-czkj="nav"]', // 选择器
    listAttr: 'data-czkj-nav="list"', // 列表属性
    start: "{haedu:site_cate_list eachparam[pid='0']/haedu}", // 开始模板
    end: "{/endhaedu}", // 结束模板
    fields: { // 字段映射
        'data-czkj-nav-url': "{@:cate_list_url:@}",
        'data-czkj-nav-name': "{@:name:@}",
        'data-czkj-nav-sed-url': "{@1:cate_list_url:1@}",
        'data-czkj-nav-sed-name': "{@1:name:1@}"
    }
});

// 注册banner模板
registerTemplateType('banner', {
    selector: '[data-czkj="banner"]',
    listAttr: 'data-czkj-banner="list"',
    start: "{haedu:banner_list eachparam[banner_id='all'] /haedu}",
    end: "{/endhaedu}",
    fields: {
        'data-czkj-banner-url': "{@:img_url:@}",
        'data-czkj-banner-img': "//{global@site_admin_url@global}{@:img:@}"
    }
});

// 注册新闻模板
templateProcessor.register('news', {
    selector: '[data-czkj="news"]',
    listAttr: 'data-czkj-news="list"',
    start: (component,limit, topid) => {
        return `{haedu:article_list eachparam[limit='${limit}';topid='${topid}';filed_len='title,60']/haedu}`;
    },
    end: "{/endhaedu}",
    fields: {
        'data-czkj-news-title': "{@:title:@}",
        'data-czkj-news-center': "{@:center:@}",
        'data-czkj-news-img': "{@:img:@}",
        'data-czkj-news-url': "{@:url:@}",
        'data-czkj-news-time-year-month': "{@:year:@}-{@:month:@}",
        'data-czkj-news-time-day': "{@:day:@}"
    }
});

// 导出方法
export function processHtmlTemplate(htmlString) {
    return templateProcessor.processHtml(htmlString);
}

export function registerTemplateType(type, config) {
    templateProcessor.register(type, config);
}